package com.liangwei.Lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 常见的卖票案列
 */
//基于Lock锁完成的售票案列
    //非公平锁：十分不公平：可以插队 （默认）
    // 公平锁：十分公平：可以先来后到 Lock lock = new ReentrantLock(true);
public class SaleTicketDemo02 {
    public static void main(String[] args) {
        //创建资源消耗
        Ticket ticket = new Ticket();
        //定义多个线程
        new Thread(() -> {
            for (int i = 0; i < 55; i++) {
                ticket.sale();
            }
        },"售票处A").start();
        new Thread(() -> {
            for (int i = 0; i < 55; i++) {
                ticket.sale();
            }
        },"售票处B").start();
        new Thread(() -> {
            for (int i = 0; i < 55; i++) {
                ticket.sale();
            }
        },"售票处C").start();
    }


    // Lock三部曲 1、 new ReentrantLock();
    // 2、 lock.lock(); 加锁
    // 3、 finally=>  lock.unlock();  解锁
    //定义资源类
    static class Ticket {
        //定义资源的属性
        private int number = 60;
        //定义可以重复使用的锁
        Lock lock = new ReentrantLock(true);
        //定义资源的方法
        public void sale() {
            //加锁
            lock.lock();
            //当不同范围内发生锁定和解锁的时候，必须确保在锁定的时候执行所有的代码由try-finally或者try-catch保护，以确保在
            //必要的时候释放锁定
            try {
                if (number > 0) {
                    System.out.println(Thread.currentThread().getName()+"卖出了"+(number--)+"票,剩余："+(number));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //释放锁
                lock.unlock();
            }
        }
    }
}
